package com.campus.secondhand.config;

import com.campus.secondhand.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

/**
 * Spring Security配置：控制哪些接口需要登录、密码加密方式、身份认证逻辑
 */
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {

    private final UserService userService;

    /**
     * 自定义用户查询逻辑（从数据库查询用户，而不是Spring Security默认的内存用户）
     */
    @Bean
    public UserDetailsService userDetailsService() {
        return username -> {
            com.campus.secondhand.entity.User user = userService.getUserByUsername(username);
            if (user == null) {
                throw new UsernameNotFoundException("用户不存在");
            }
            // 构建Spring Security需要的用户对象（包含用户名、加密后的密码、角色）
            return org.springframework.security.core.userdetails.User
                    .withUsername(user.getUsername())
                    .password(user.getPassword())
                    .roles(user.getRole() == 1 ? "ADMIN" : "USER")  // 0=普通用户，1=管理员
                    .build();
        };
    }

    /**
     * 密码加密器（用户注册时密码加密存储，登录时解密验证）
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();  // 不可逆加密，安全系数高
    }

    /**
     * 认证提供者（关联用户查询逻辑和密码加密器）
     */
    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setUserDetailsService(userDetailsService());
        provider.setPasswordEncoder(passwordEncoder());
        return provider;
    }

    /**
     * 认证管理器（处理用户登录认证逻辑）
     */
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
        return config.getAuthenticationManager();
    }

    /**
     * 安全过滤链：配置接口权限、会话策略
     */
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .csrf(csrf -> csrf.disable())  // 关闭CSRF（前后端分离项目不需要）
                .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))  // 无状态会话（用JWT代替session）
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/user/register", "/user/login").permitAll()  // 公开接口（无需登录）
                        .requestMatchers("/admin/**").hasRole("ADMIN")  // 管理员接口（需ADMIN角色）
                        .anyRequest().authenticated()  // 其他接口都需要登录认证
                );

        http.authenticationProvider(authenticationProvider());  // 启用认证提供者

        return http.build();
    }
}